package com.fintech.common.util;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

import com.marvels.common.utils.MarvelsLogUtil;

import sun.misc.BASE64Encoder;

public class MD5Utils {  
	
	public static String getMD5(String str) {
	        MessageDigest md;
			try {
				md = MessageDigest.getInstance("MD5");
		        md.update(str.getBytes());
		        return new BigInteger(1, md.digest()).toString(16);
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
				return null;
			}
	}
	
	public static void main(String[] args) {
		String md5 = getMD5("admin");
		System.out.println(md5);
	}
	
	/**
	 * MD5加密返回16进制字符串（默认UTF-8）
	 * 
	 * @param sourceData
	 *            待加密字符串
	 * @return
	 */
	public static String md5WithHex(String sourceData) {
		return md5WithHex(sourceData, "UTF-8");
	}

	/**
	 * MD5加密返回16进制字符串
	 * 
	 * @param sourceData
	 *            待加密字符串
	 * @param charSet
	 *            字符集编码
	 * @return
	 */
	public static String md5WithHex(String sourceData, String charSet) {
		// 如果有空则返回""
		String s = sourceData == null ? "" : sourceData;
		try {
			// 将字符串转为字节数组
			byte[] strTemp = s.getBytes(charSet);
			// 加密器
			MessageDigest mdTemp = MessageDigest.getInstance("MD5");
			// 执行加密
			mdTemp.update(strTemp);
			// 加密结果
			byte[] byteArray = mdTemp.digest();
			return Hex.encodeHexString(byteArray);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("md5WithHex 出现异常", e);
			return null;
		}
	}

	/**
	 * MD5加密返回BASE64编码（默认UTF-8）
	 * 
	 * @param sourceData
	 *            待加密字符串
	 * @return
	 */
	public static String md5WithBase64(String sourceData) {
		return md5WithBase64(sourceData, "UTF-8");
	}
	
	/**
	 * MD5加密返回BASE64编码
	 * 
	 * @param sourceData
	 *            待加密字符串
	 * @param charSet
	 *            字符集编码
	 * @return
	 */
	public static String md5WithBase64(String sourceData, String charSet) {
		// 如果有空则返回""
		String s = sourceData == null ? "" : sourceData;
		try {
			// 将字符串转为字节数组
			byte[] strTemp = s.getBytes(charSet);
			// 加密器
			MessageDigest mdTemp = MessageDigest.getInstance("MD5");
			// 执行加密
			mdTemp.update(strTemp);
			// 加密结果
			byte[] byteArray = mdTemp.digest();
			return Base64.encodeBase64URLSafeString(byteArray);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("md5WithBase64 出现异常", e);
			return null;
		}
	}
	
	/**
	 * 先进行MD5加密 然后使用base64编码
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static String encoderByMd5(String str) throws Exception {
		// 确定计算方法
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		BASE64Encoder base64en = new BASE64Encoder();
		// 加密后的字符串
		String newstr = base64en.encode(md5.digest(str.getBytes("utf-8")));
		return newstr;
	}
	
	public static String build(String origin) {
	      if (origin == null)
	          return null;
	  
	      StringBuilder sb = new StringBuilder();
	      MessageDigest digest = null;
	      try {
	          digest = MessageDigest.getInstance("MD5");
	      } catch (NoSuchAlgorithmException e) {
	          e.printStackTrace();
	          return null;
	      }
	  
	      byte[] bs = null;
	      try {
	          bs = digest.digest(origin.getBytes("UTF-8"));
	      } catch (UnsupportedEncodingException e) {
	          e.printStackTrace();
	          return null;
	      }
	  
	      for (int i = 0; i < bs.length; i++) {
	          int c = bs[i] & 0xFF;
	          if (c < 16) {
	              sb.append("0");
	          }
	          sb.append(Integer.toHexString(c));
	      }
	      return sb.toString();
	  }
	  
	  public static String build(String origin,String salt) {
	    if (origin == null)
	        return null;
	  
	    StringBuilder sb = new StringBuilder();
	    MessageDigest digest = null;
	    try {
	        digest = MessageDigest.getInstance("MD5");
	        digest.update(salt.getBytes("UTF-8"));
	    } catch (NoSuchAlgorithmException e) {
	        e.printStackTrace();
	        return null;
	    } catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
	  
	    byte[] bs = null;
	    try {
	        bs = digest.digest(origin.getBytes("UTF-8"));
	    } catch (UnsupportedEncodingException e) {
	        e.printStackTrace();
	        return null;
	    }
	  
	    for (int i = 0; i < bs.length; i++) {
	        int c = bs[i] & 0xFF;
	        if (c < 16) {
	            sb.append("0");
	        }
	        sb.append(Integer.toHexString(c));
	    }
	    return sb.toString();
	  }
	  
	  public static boolean validataSignWithMd5(String sign, String origin, String salt) {
		  String md5Sign = build(origin, salt);
		  return StringUtils.equals(sign, md5Sign);
	  }
    
	
}  